package com.ocom.accesservice.controller;

import com.github.pagehelper.PageInfo;
import com.ocom.accesservice.service.AreaInfoService;
import com.ocom.accesservice.service.CompanyListInfoService;
import com.ocom.accesservice.service.DeviceInfoService;
import com.ocom.common.constant.AccessServiceUrl;
import com.ocom.common.dto.SearchMachListDto;
import com.ocom.common.entity.access.EntityMjAreaInfo;
import com.ocom.common.entity.access.EntityMjDeviceInfo;
import com.ocom.common.entity.master.EntityCompanyList;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.srvpaccess.FindMachDto;
import com.ocom.common.request.srvpaccess.FindMachVo;
import com.ocom.common.request.srvpaccess.UpdateMachByAlarmRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.*;
import com.ocom.common.vo.access.MjDeviceInfoExxVo;
import com.ocom.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@RestController
public class DeviceListController {
    private final Logger log = LoggerFactory.getLogger(DeviceListController.class);

    @Autowired
    private DeviceInfoService deviceInfoService;


    @Autowired
    private AreaInfoService areaInfoService;

    @Autowired
    private CompanyListInfoService companyListInfoService;


    @Resource
    private RedisUtil redisUtil;

    /**
     * 查询设备列表（searchMachList）
     */
    @PostMapping(AccessServiceUrl.URL_SearchMachList)
    public Result SearchMachList(@Validated @RequestBody SearchMachListVo searchMachListVo) {
        Map<String, Object> map = new HashMap<>();
        if (searchMachListVo != null) {
            List<MjDeviceInfoExxVo> list1 = deviceInfoService.SearchMachList(searchMachListVo, searchMachListVo.getComId());
            list1.forEach(item -> {
                item.setCommTime(getCommTime(item.getDeviceNo(),item.getCommTime()));
            });
            if (list1.size() > 0) {
                PageInfo<MjDeviceInfoExxVo> entityMjDeviceInfoPageInfo = new PageInfo<>(list1);
                List<SearchMachListDto> listDtos = new ArrayList<>();
                for (MjDeviceInfoExxVo entityMjDeviceInfo : list1) {
                    SearchMachListDto searchMachListDto = new SearchMachListDto();
                    //封装返回字段
                    searchMachListDto.setComId(entityMjDeviceInfo.getComId());
                    searchMachListDto.setDeviceName(entityMjDeviceInfo.getDeviceName());
                    searchMachListDto.setDeviceNo(entityMjDeviceInfo.getDeviceNo());
                    searchMachListDto.setDeviceId(entityMjDeviceInfo.getDeviceId());
                    searchMachListDto.setAreaId(entityMjDeviceInfo.getAreaId());
                    searchMachListDto.setCreateTime(entityMjDeviceInfo.getCreateTime());
                    searchMachListDto.setEndTime(entityMjDeviceInfo.getEndTime());
                    searchMachListDto.setCommTime(entityMjDeviceInfo.getCommTime());
                    searchMachListDto.setDeviceType(entityMjDeviceInfo.getDeviceType());
                    searchMachListDto.setDeviceVerType(entityMjDeviceInfo.getDeviceVerType());
                    searchMachListDto.setDeviceMode(entityMjDeviceInfo.getDeviceMode());
                    searchMachListDto.setAppVer(entityMjDeviceInfo.getAppVer());
                    searchMachListDto.setAppVerTab(entityMjDeviceInfo.getAppVerTab());
                    searchMachListDto.setFaceAuthCode(entityMjDeviceInfo.getFaceAuthCode());
                    searchMachListDto.setOpenType(entityMjDeviceInfo.getOpenType());

                    searchMachListDto.setIfAlarm(entityMjDeviceInfo.getIfAlarm());
                    searchMachListDto.setAlarmTimes(entityMjDeviceInfo.getAlarmTimes());

                    searchMachListDto.setWhiteUrl(entityMjDeviceInfo.getWhiteUrl());
                    searchMachListDto.setWhiteFace(entityMjDeviceInfo.getWhiteFace());
                    searchMachListDto.setWhiteErrFace(entityMjDeviceInfo.getWhiteErrFace());
                    searchMachListDto.setWhiteUser(entityMjDeviceInfo.getWhiteUser());

                    searchMachListDto.setStatus(entityMjDeviceInfo.getStatus());
                    EntityMjAreaInfo entityMjAreaInfo = areaInfoService.getAreaById(entityMjDeviceInfo.getAreaId(), searchMachListVo.getComId());
                    if (entityMjAreaInfo == null) {
                        listDtos.add(searchMachListDto);
                        continue;
                    }
                    searchMachListDto.setAreaName("");
                    if (!CommonUtil.isNull(entityMjAreaInfo.getAreaName())) {
                        searchMachListDto.setAreaName(entityMjAreaInfo.getAreaName());
                    }
                    listDtos.add(searchMachListDto);
                }


                map.put("total", entityMjDeviceInfoPageInfo.getTotal());
                map.put("list", listDtos);
            }
            return ResultUtil.success(map);
        } else {
            return ResultUtil.success();
        }
    }


    /**
     * 按出厂号登记设备（bindMachVo）
     */
    @PostMapping(AccessServiceUrl.URL_BindMach)
    public Result BindMach(@Validated @RequestBody BindMachVo bindMachVo) {
        log.info(" 按出厂号登记设备（bindMachVo）{{}}", bindMachVo);
        if (bindMachVo.getComId() == null) {
            log.error("按出厂号登记设备（bindMachVo）单位编号为空");
            return ResultUtil.error(ResultEnum.Err_203, "按出厂号登记设备（bindMachVo）单位编号为空");
        }
        if (bindMachVo.getDeviceNo().isEmpty()) {
            log.error("按出厂号登记设备（bindMachVo）出厂号为空");
            return ResultUtil.error(ResultEnum.Err_203, "按出厂号登记设备（bindMachVo）出厂号为空");
        }

        try {
            //删除status为1的记录
            deviceInfoService.DeleteMach(bindMachVo.getComId(), bindMachVo.getDeviceNo());
        } catch (Exception exception) {
            log.error("按出厂号登记设备（bindMachVo）删除门禁设备状态为禁用操作失败" + exception.getMessage());
            return ResultUtil.error(ResultEnum.Err_2009, "按出厂号登记设备（bindMachVo）删除门禁设备状态为禁用操作失败");
        }

        try {
            //4、分库mj_device_info表添加1条记录：
            deviceInfoService.BindMach(bindMachVo, bindMachVo.getComId());
        } catch (Exception exception) {
            log.error("按出厂号登记设备（bindMachVo）失败：" + exception.getMessage());
            return ResultUtil.error(ResultEnum.Err_2009, "按出厂号登记设备（bindMachVo）失败");
        }
        return ResultUtil.success();
    }


    /**
     * 按出厂号批量导入登记设备（ImportMach）
     */
    @PostMapping(AccessServiceUrl.URL_ImportMach)
    public Result ImportMach(@Validated @RequestBody List<ImportMachVo> importMachVos) {
        //如果有end_time<当前系统时间，则删除总库mj_device_表和分库mj_device_info表的记录
        //如果有end_time>=当前系统时间则返回错误
        //校验使用时间end_time>=当前时间。
        for (ImportMachVo importMachVo : importMachVos) {

            //校验deviceno值
            //  1、总库mj_device_ list表查找device_no= machNo，status=0的记录，有则返回错误
            //2、总库mj_device_ list表查找device_no= machNo，status=1的记录，如果有:
            try {
                //删除status为1的记录
                deviceInfoService.DeleteMach(importMachVo.getComId(), importMachVo.getDeviceNo());
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }

        try {
            //4、分库mj_device_info表添加1条记录：
            deviceInfoService.WebImportMach(importMachVos, importMachVos.get(0).getComId());
        } catch (Exception exception) {
            exception.printStackTrace();
            return ResultUtil.error(ResultEnum.Err_2009);
        }

        return ResultUtil.success();
    }


    /**
     * 修改设备（updateMach）
     */
    @PostMapping(AccessServiceUrl.URL_UpdateMach)
    public Result UpdateMach(@Validated @RequestBody UpdateMachVo updateMachVo) {

        deviceInfoService.UpdateMach(updateMachVo, updateMachVo.getComId());
        return ResultUtil.success();
    }

    /**
     * 修改安装位置（changeMachPlace）
     */
    @PostMapping(AccessServiceUrl.URL_ChangeMachPlace)
    public Result ChangeMachPlace(@Validated @RequestBody ChangeMachPlaceVo changeMachPlaceVo) {

        try {
            deviceInfoService.ChangeMachPlace(changeMachPlaceVo, changeMachPlaceVo.getComId());
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return ResultUtil.success();
    }

    @PostMapping(AccessServiceUrl.Url_AccessDeviceGetDeviceByDeviceNo)
    public Result<EntityMjDeviceInfo> GetDeviceByDeviceNo(@Validated @RequestParam String deviceNo, @RequestParam Long comId) {
        return ResultUtil.success(deviceInfoService.GetDeviceByDeviceNo(deviceNo, comId));
    }

    /**
     * 移除设备（removeMach）
     */
    @PostMapping(AccessServiceUrl.URL_RemoveMach)
    public Result RemoveMach(String deviceNo, Long comId, Integer pId) {
        if (comId == null) {
            log.error("移除设备（removeMach）单位编号为空");
            return ResultUtil.error(ResultEnum.Err_203, "移除设备（removeMach）单位编号为空");
        }
        if (deviceNo.isEmpty()) {
            log.error("移除设备（removeMach）出厂号为空");
            return ResultUtil.error(ResultEnum.Err_203, "移除设备（removeMach）出厂号为空");
        }
        if (pId == null) {
            log.error("移除设备（removeMach）管理员编号为空");
            return ResultUtil.error(ResultEnum.Err_203, "移除设备（removeMach）管理员编号为空");
        }

        try {
            deviceInfoService.RemoveMach(comId, deviceNo);
        } catch (Exception exception) {
            log.error("执行移除设备（removeMach）失败：" + exception.getMessage());
            exception.printStackTrace();
            return ResultUtil.error(ResultEnum.Err_2009, "执行移除设备（removeMach）失败");
        }
        return ResultUtil.success();
    }

    /**
     * 门禁设备列表（AccessDevice/allOnShow）
     */
    @PostMapping(AccessServiceUrl.URL_FindMach)
    public Result FindMach(@Validated @RequestBody FindMachVo findMachVo) {
        //1、根据查询条件从分库mj_device_info表查找记录
        //如果comId> 0：查找com_id= comId的记录
        Map<String, Object> map = new HashMap<>();
        assert findMachVo.getComId() != null;
        if (findMachVo.getComId() > 0) {
            List<EntityMjDeviceInfo> deviceInfos = deviceInfoService.FindMach(findMachVo.getComId(), findMachVo);
            PageInfo<EntityMjDeviceInfo> entityMjDeviceListPageInfo = new PageInfo<>(deviceInfos);
            List<FindMachDto> listDtos = new ArrayList<>();
            if (deviceInfos.size() != 0) {
                for (EntityMjDeviceInfo entityMjDeviceInfo : deviceInfos) {
                    FindMachDto findMachDto1 = new FindMachDto();
                    findMachDto1.setDeviceNo(entityMjDeviceInfo.getDeviceNo());
                    findMachDto1.setDeviceName(entityMjDeviceInfo.getDeviceName());

                    findMachDto1.setComId(entityMjDeviceInfo.getComId());
                    findMachDto1.setAreaId(entityMjDeviceInfo.getAreaId());
                    findMachDto1.setEndTime(entityMjDeviceInfo.getEndTime());
                    findMachDto1.setCommTime(entityMjDeviceInfo.getCommTime());
                    findMachDto1.setDeviceType(entityMjDeviceInfo.getDeviceType());
                    findMachDto1.setAppVer(entityMjDeviceInfo.getAppVer());
                    //2、如果com_id>0，从分库门禁设备表mj_device_info查找其它字段
                    //封装返回字段
                    findMachDto1.setStatus(entityMjDeviceInfo.getStatus());
                    findMachDto1.setCreateTime(entityMjDeviceInfo.getCreateTime());
                    EntityMjAreaInfo entityMjAreaInfo = areaInfoService.getAreaById(entityMjDeviceInfo.getAreaId(), entityMjDeviceInfo.getComId());
                    if (entityMjAreaInfo == null) {
                        listDtos.add(findMachDto1);
                        continue;
                    }
                    findMachDto1.setAreaName(entityMjAreaInfo.getAreaName());

                    listDtos.add(findMachDto1);
                }


            }
            map.put("total", entityMjDeviceListPageInfo.getTotal());
            map.put("list", listDtos);
        }
        //如果agentId> 0：先从总库单位列表company_list查找agent_id= agentId的所有记录
        if (findMachVo.getAgentId() != null) {
            List<EntityCompanyList> entityCompanyLists = companyListInfoService.FindMachComId(findMachVo.getAgentId());
            for (EntityCompanyList entityCompanyList : entityCompanyLists) {
                findMachVo.setComId(entityCompanyList.getComId());
                List<EntityMjDeviceInfo> entityMjDeviceInfos = deviceInfoService.FindMach(entityCompanyList.getComId(), findMachVo);

                PageInfo<EntityMjDeviceInfo> mjDeviceInfoPageInfo = new PageInfo<>(entityMjDeviceInfos);
                List<FindMachDto> findMachDtos = new ArrayList<>();
                if (entityMjDeviceInfos.size() != 0) {
                    for (EntityMjDeviceInfo entityMjDeviceInfo : entityMjDeviceInfos) {
                        FindMachDto findMachDto1 = new FindMachDto();
                        findMachDto1.setDeviceNo(entityMjDeviceInfo.getDeviceNo());
                        findMachDto1.setDeviceName(entityMjDeviceInfo.getDeviceName());

                        findMachDto1.setComId(entityMjDeviceInfo.getComId());
                        findMachDto1.setAreaId(entityMjDeviceInfo.getAreaId());
                        findMachDto1.setEndTime(entityMjDeviceInfo.getEndTime());
                        findMachDto1.setCommTime(entityMjDeviceInfo.getCommTime());
                        findMachDto1.setDeviceType(entityMjDeviceInfo.getDeviceType());
                        findMachDto1.setAppVer(entityMjDeviceInfo.getAppVer());
                        //2、如果com_id>0，从分库门禁设备表mj_device_info查找其它字段
                        //封装返回字段
                        findMachDto1.setStatus(entityMjDeviceInfo.getStatus());
                        findMachDto1.setCreateTime(entityMjDeviceInfo.getCreateTime());
                        EntityMjAreaInfo entityMjAreaInfo = areaInfoService.getAreaById(entityMjDeviceInfo.getAreaId(), entityMjDeviceInfo.getComId());
                        if (entityMjAreaInfo == null) {
                            findMachDtos.add(findMachDto1);
                            continue;
                        }
                        findMachDto1.setAreaName(entityMjAreaInfo.getAreaName());

                        findMachDtos.add(findMachDto1);
                    }
                }
                map.put("total", mjDeviceInfoPageInfo.getTotal());
                map.put("list", findMachDtos);
            }

        }
        return ResultUtil.success(map);
    }

    /**
     * 门禁设备列表（AccessDevice/allOnShow）
     */
    @PostMapping(AccessServiceUrl.URL_FindMach2)
    public Result FindMach2(@Validated @RequestBody FindMachVo findMachVo) {
        //1、根据查询条件从分库mj_device_info表查找记录
        //如果comId> 0：查找com_id= comId的记录
        Map<String, Object> map = new HashMap<>();


        List<EntityMjDeviceInfo> deviceInfos = deviceInfoService.FindMach2(findMachVo.getComId(), findMachVo);
        PageInfo<EntityMjDeviceInfo> entityMjDeviceListPageInfo = new PageInfo<>(deviceInfos);
        List<FindMachDto> listDtos = new ArrayList<>();
        if (deviceInfos.size() != 0) {
            for (EntityMjDeviceInfo entityMjDeviceInfo : deviceInfos) {
                FindMachDto findMachDto1 = new FindMachDto();
                findMachDto1.setDeviceNo(entityMjDeviceInfo.getDeviceNo());
                findMachDto1.setDeviceName(entityMjDeviceInfo.getDeviceName());

                findMachDto1.setComId(entityMjDeviceInfo.getComId());
                findMachDto1.setAreaId(entityMjDeviceInfo.getAreaId());
                findMachDto1.setEndTime(entityMjDeviceInfo.getEndTime());
                findMachDto1.setCommTime(entityMjDeviceInfo.getCommTime());
                findMachDto1.setDeviceType(entityMjDeviceInfo.getDeviceType());
                findMachDto1.setAppVer(entityMjDeviceInfo.getAppVer());

                findMachDto1.setIfAlarm(entityMjDeviceInfo.getIfAlarm());
                findMachDto1.setAlarmState(entityMjDeviceInfo.getAlarmState());
                findMachDto1.setAlarmTimes(entityMjDeviceInfo.getAlarmTimes());

                //2、如果com_id>0，从分库门禁设备表mj_device_info查找其它字段
                //封装返回字段
                findMachDto1.setStatus(entityMjDeviceInfo.getStatus());
                findMachDto1.setCreateTime(entityMjDeviceInfo.getCreateTime());
                EntityMjAreaInfo entityMjAreaInfo = areaInfoService.getAreaById(entityMjDeviceInfo.getAreaId(), entityMjDeviceInfo.getComId());
                if (entityMjAreaInfo == null) {
                    listDtos.add(findMachDto1);
                    continue;
                }
                findMachDto1.setAreaName(entityMjAreaInfo.getAreaName());
                findMachDto1.setUserName(entityMjAreaInfo.getUserName());

                listDtos.add(findMachDto1);
            }


            map.put("total", entityMjDeviceListPageInfo.getTotal());
            map.put("list", listDtos);
        }
        return ResultUtil.success(map);
    }


    @PostMapping(AccessServiceUrl.URL_updateMachByAlarm)
    public Result updateMachByAlarm(@Validated @RequestBody UpdateMachByAlarmRequest request) {
        deviceInfoService.updateMachByAlarm(request.getComId(), request.getAlarmState(), request.getDeviceNos());
        return ResultUtil.success();
    }


    private Date getCommTime(String machNo, Date commTime){
        Object obj = redisUtil.get("HttpMJMachCommTime:"+machNo);
        if(obj!=null){
            return (Date) obj;
        }
        if(commTime==null){
            commTime = DateUtils.strToDate("2020-01-01 12:34:56");
        }
        redisUtil.set("HttpMJMachCommTime:"+machNo,commTime);
        return commTime;
    }



    @PostMapping(AccessServiceUrl.Url_delSession)
    public Result delSession(@RequestParam("comId") Long comId){
        deviceInfoService.deleteSession(comId);
        return ResultUtil.success();
    }
}